import { ErrorRoute } from '@/router/index';
import { storage } from '@/utils/Storage';
import { LOGIN_PATH, TOKEN_KEY } from '@/enums/commEnum';
import { useUserStoreOut } from '@/store/useUserStore';
import type { Router, RouteRecordRaw } from 'vue-router';
import { useAuthStoreOut } from '@/store/useAuthStore';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';

const whiteList = [LOGIN_PATH];

export function createRouterGuards(router: Router) {
  const userStore = useUserStoreOut();
  const authStore = useAuthStoreOut();

  router.beforeEach(async (to, from, next) => {
    NProgress.start();

    // Whitelist can be directly entered
    if (whiteList.includes(to.path)) {
      next();
      return;
    }

    const token = storage.get(TOKEN_KEY);
    if (!token) {
      // redirect login page
      const redirectData: { path: string; replace: boolean; query?: any } = {
        path: LOGIN_PATH,
        replace: true,
      };
      if (to.path) {
        redirectData.query = {
          ...redirectData.query,
          redirect: to.path,
        };
      }
      next(redirectData);
      return;
    }

    if (authStore.isRouteGenerated) {
      next();
      return;
    }

    try {
      await userStore.current();
    } catch (e) {
      console.error(e);
      await userStore.resetToken();
      next({ path: LOGIN_PATH, replace: true });
      return;
    }

    let routes = authStore.generateRoutes();
    // 动态添加可访问路由表
    routes.forEach((item) => {
      router.addRoute(item as unknown as RouteRecordRaw);
    });

    //添加404
    const isErrorPage = router.getRoutes().findIndex((item) => item.name == ErrorRoute.name);
    if (isErrorPage === -1) {
      router.addRoute(ErrorRoute as unknown as RouteRecordRaw);
    }

    authStore.setRouteGenerated(true);
    next({ ...to, replace: true });
  });

  router.afterEach((to, _, failure) => {
    document.title = (to?.meta?.title as string) || document.title;

    let authStore = useAuthStoreOut();
    let keepAliveComponents = authStore.keepAliveComponents;
    const currentComName = to.matched.find((item) => item.name == to.name)?.name as string;
    if (currentComName && !keepAliveComponents.includes(currentComName) && to.meta?.keepAlive) {
      // 需要缓存的组件
      keepAliveComponents.push(currentComName);
    } else if (!to.meta?.keepAlive) {
      // 不需要缓存的组件
      const index = authStore.keepAliveComponents.findIndex((name) => name == currentComName);
      if (index !== -1) {
        keepAliveComponents.splice(index, 1);
      }
    }
    authStore.setKeepAliveComponents(keepAliveComponents);

    NProgress.done();
  });
}
